﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MAF.Common;

namespace MAF
{
    /// <summary>
    /// 查询条件类
    /// </summary>
    public class Criterion : IQuery
    {
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="field"></param>
        /// <param name="op"></param>
        /// <param name="value"></param>
        public Criterion(string field, Compares op, object value)
        {
            Field = field;
            Op = op;
            Value = value;
        }

        #region 属性

        /// <summary>
        /// 字段
        /// </summary>
        public string Field { get; private set; }

        /// <summary>
        /// 操作
        /// </summary>
        public Compares Op { get; private set; }

        /// <summary>
        /// 值
        /// </summary>
        public object Value { get; private set; }

        #endregion

        #region 方法

        /// <summary>
        /// 查询条件是否匹配参数指定的对象
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public bool IsMatch(object target)
        {
            // 获取类型
            Type targetType = target.GetType();

            // 创建对象
            //object objInstance = Activator.CreateInstance(objType);
            var arry = Field.Split(". ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            // 判断属性是否存在
            if (!ReflectHelper.IsExistsMember(targetType, Field))
                return false;

            // 获取属性值
            object val = ReflectHelper.GetMemberValue(target, arry[0]);

            // 处理null的情景
            if (null == val)
                return val == Value;

            // 处理其他情景
            if (1 < arry.Length)
            {
                for (int i = 1, len = arry.Length; i < len; ++i)
                {
                    Type tempType = val.GetType();
                    val = ReflectHelper.GetMemberValue(val, arry[i]);
                }
            }

            if (val is string && Compares.Like == this.Op)
            {
                return -1 < (val as string).IndexOf(Value as string);
            }
            else if (val is IComparable) // 判断是否具有IComparable接口，以确定是否存在CompareTo()方法
            {
                var r = (val as IComparable).CompareTo(Value);
                switch (this.Op)
                {
                    case Compares.Equals:
                        return 0 == r;
                    case Compares.GreaterThan:
                        return 0 < r;
                    case Compares.GreaterThanOrEquals:
                        return 0 <= r;
                    case Compares.LessThan:
                        return 0 > r;
                    case Compares.LessThanOrEquals:
                        return 0 >= r;
                    default:
                        throw new ArgumentException("不存在操作符"+ this.Op.ToString());
                }
            }

            return false;
        }

        #endregion

        /// <summary>
        /// 叶子节点不需要实现吃方法
        /// </summary>
        /// <param name="q"></param>
        public void Add(IQuery q)
        {
            throw new NotImplementedException();
        }
    }
}
